<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\Config;
use app\common\model\question\Banner;
use app\common\model\question\Category;
use app\common\model\question\Exam;
use app\common\model\question\Notice;
use app\common\model\question\Question as QuestionModel;
use app\common\model\question\QuestionUser;
use app\common\model\question\Type;
use fast\Tree;

/**
 * 题库接口
 */
class Question extends Api
{
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = ['category', 'type', 'layout', 'banner', 'notice'];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['*'];

    public function category()
    {
        $category = Category::where('display_switch', Category::SWITCH_Y)->order('weigh', 'desc')->field(['id', 'pid', 'name', 'vip'])->select();
        $list = Tree::instance()->init($category)->getTreeArray(0);
        $this->success('', $list);
    }

    public function type()
    {
        $type = Type::order('weigh', 'desc')->field(['id', 'name'])->select();
        $this->success('', $type);
    }

    public function layout()
    {
        $layout = Config::where('name', 'layout')->find();
        $this->success('', json_decode($layout->value, true));
    }

    public function banner()
    {
        $category_id = $this->request->get('category_id', 0);

        $list = Banner::where('display_switch', Banner::SWITCH_Y)
            ->where('question_category_id', $category_id)
            ->select();
        $this->success('', $list);
    }

    public function baseInfo()
    {
        $info = Config::whereIn('name', ['about', 'privacy', 'agreement', 'beian'])->select();
        $this->success('', $info);
    }

    public function list()
    {
        $user_id = $this->auth->id;
        $id = (int)$this->request->get('id', 0);
        $category_id = (int)$this->request->get('category_id', 0);
        $random = (int)$this->request->get('random', 0);
        $type_id = $this->request->get('type_id', 0);
        $type_id = $type_id ? explode(',', $type_id) : [];
        $title = $this->request->get('title', '');
        $star = $this->request->get('star');
        $right = $this->request->get('right');
        $answer = $this->request->get('answer');
        $paper = $this->request->get('paper');

        $list = QuestionModel::alias('q')
            ->join('question_user qu', "qu.question_id = q.id and qu.user_id = {$user_id}", 'left')
            ->where('q.display_switch', QuestionModel::SWITCH_Y)
            ->where('q.question_category_id', $category_id)
            ->where(function ($query) use ($id, $user_id, $type_id, $title, $right, $star, $answer) {
                if ($id) {
                    $query->where('q.id', $id);
                }
                if ($type_id) {
                    $query->whereIn('q.question_type_id', $type_id);
                }
                if ($title) {
                    $query->whereLike('q.title', "%{$title}%");
                }
                if (!is_null($right)) {
                    $query->where('qu.right', (int)(bool)$right);
                }
                if ($star) {
                    $query->where('qu.star', (int)(bool)$star);
                }
                if (!is_null($answer)) {
                    $query->whereNull('qu.answer');
                }
            })
            ->order('q.id', 'desc')->field('q.*, qu.answer user_answer, qu.right, qu.star')->select();
        if ($random) {
            $list = $list->shuffle();
        }

        if ($paper) {
            $types = Type::field(['id', 'name', 'num'])->select()->toArray();
            $types_name = array_column($types, 'name', 'id');

            $list = $list->shuffle();
            $exams = Category::field(['exam'])->where('id', $category_id)->find()->toArray();
            $data = $this->groupBy($list, 'question_type_id');
            $q = [];
            foreach ($exams['exam'] as &$v) {
                $arr = array_slice($data[$v['id']] ?? [], 0, $v['num']);
                $v['num'] = count($arr);
                $v['name'] = $types_name[$v['id']] ?? '';
                $v['score'] = (float)$v['score'];
                $v['id'] = (int)$v['id'];
                $q = array_merge($q, $arr);
            }
            unset($v);
            $type_map = array_values($exams['exam']);
            if (!$q) {
                foreach ($types as &$v) {
                    $arr = array_slice($data[$v['id']] ?? [], 0, $v['num']);
                    $v['num'] = count($arr);
                    $v['score'] = 1;
                    $q = array_merge($q, $arr);
                }
                unset($v);
                $type_map = $types;
            }

            $list = [
                'total' => count($q),
                'type' => $type_map,
                'list' => $q,
            ];
        }

        $this->success('', $list);
    }

    public function userAnswer()
    {
        $user = $this->auth->getUser();
        $question_id = (int)$this->request->post('question_id', 0);
        $answer = $this->request->post('answer');
        if (!$question_id || !$answer) {
            $this->error('参数错误');
        }
        $question = QuestionModel::where('id', $question_id)->find();
        if (!$question) {
            $this->error('题目不存在');
        }
        $log = QuestionUser::where([
            'question_id' => $question->id,
            'user_id' => $user->id,
        ])->find();
        if ($log) {
            $log->question_category_id = $question->question_category_id;
            $log->answer = $answer;
            $log->right = (int)($answer == $question->answer_tags);
            $log->nums++;
            $log->save();
        } else {
            QuestionUser::create([
                'question_category_id' => $question->question_category_id,
                'question_id' => $question->id,
                'user_id' => $user->id,
                'answer' => $answer,
                'right' => (int)($answer == $question->answer_tags),
                'nums' => 1,
            ]);
        }

        $this->success();
    }

    public function userStar()
    {
        $user = $this->auth->getUser();
        $question_id = (int)$this->request->post('question_id');
        $star = (int)(bool)$this->request->post('star', 0);

        $question = QuestionModel::where('id', $question_id)->find();
        if (!$question) {
            $this->error('题目不存在');
        }

        $log = QuestionUser::where([
            'question_id' => $question->id,
            'user_id' => $user->id,
        ])->find();
        if (!$log) {
            if ($star) {
                QuestionUser::create([
                    'question_category_id' => $question->question_category_id,
                    'question_id' => $question_id,
                    'user_id' => $user->id,
                    'star' => $star,
                ]);
            }
        } else {
            if ($star || $log->nums) {
                $log->star = $star;
                $log->save();
            } else {
                $log->delete();
            }
        }

        $this->success();
    }

    public function statistics()
    {
        $user_id = $this->auth->id;
        $category_id = (int)$this->request->get('category_id', 0);
        $total = QuestionModel::where('display_switch', QuestionModel::SWITCH_Y)->where('question_category_id', $category_id)->count();
        $log = QuestionUser::where('user_id', $user_id)
            ->where('question_category_id', $category_id)
            ->where('nums', '>', 0)
            ->group('right')->fieldRaw('`right`, count(*) num')->select()->column('num', 'right');
        $this->success('', [
            'total' => $total,
            'user_total' => $log ? array_sum($log) : 0,
            'user_true' => $log ? $log[1] ?? 0 : 0,
            'user_false' => $log ? $log[0] ?? 0 : 0,
        ]);
    }

    public function notice()
    {
        $category_id = (int)$this->request->get('category_id', 0);
        $type = (int)$this->request->get('type', 1);
        $list = Notice::where('display_switch', Notice::SWITCH_Y)
            ->where('question_category_id', $category_id)
            ->where('type', $type)
            ->order('updatetime', 'desc')
            ->select();
        $this->success('', $list);
    }

    private function groupBy($arr, $key_field)
    {
        $ret = array();
        foreach ($arr as $row) {
            $key = $row [$key_field];
            $ret [$key] [] = $row;
        }
        return $ret;
    }

    public function examSave()
    {
        $user = $this->auth->getUser();
        $category_id = (int)$this->request->post('category_id', 0);
        $answer = $this->request->post('answer', '');
        $score = $this->request->post('score');
        $take_time = $this->request->post('take_time');
        $false_num = (int)$this->request->post('false_num');
        $true_num = (int)$this->request->post('true_num');
        if (!$category_id || !$answer || !$take_time) {
            $this->error('参数错误');
        }
        Exam::create([
            'user_id' => $user->id,
            'question_category_id' => $category_id,
            'answer' => $answer,
            'score' => $score,
            'false_num' => $false_num,
            'true_num' => $true_num,
            'take_time' => $take_time,
        ]);

        $this->success();
    }
}
